#pragma once

#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include "msli/entities/Point.hpp"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T>
void ReadDataFromFileWithNotOid(const std::string &filename, std::vector<Point<T>> &datas) {
    std::ifstream infile(filename);
    if (!infile.is_open()) {
        std::cerr << "无法打开文件 " << filename << std::endl;
    }

    std::string line;
    OID_TYPE Id = 0;
    while (std::getline(infile, line)) {
        std::istringstream iss(line);
        std::string value;
        std::vector<COEFF_TYPE> coords;

        while (getline(iss, value, ',')) {
            coords.push_back(atof(value.c_str()));
        }

        datas.emplace_back(coords, Id++);
    }

    infile.close();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T>
void ReadDataFromFileWithID(const std::string &filename, std::vector<Point<T>> &datas) {
    std::ifstream infile(filename);
    if (!infile.is_open()) {
        std::cerr << "无法打开文件 " << filename << std::endl;
    }

    std::string line;
    while (std::getline(infile, line)) {
        std::istringstream iss(line);
        std::string value;
        Point<T> point;
        std::vector<COEFF_TYPE> coords;

        if (!getline(iss, value, ',')) {
            std::cerr << "读取 id 时出错。" << std::endl;
            continue;
        }
        point.id = atoi(value.c_str());

        while (getline(iss, value, ',')) {
            coords.push_back(atof(value.c_str()));
        }

        if (coords.size() < 2) {
            std::cerr << "坐标数量不正确。" << std::endl;
            continue;
        }

        point.coords = coords;
        datas.emplace_back(point);
    }

    infile.close();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T>
void ReadDataFromFile_Query(const std::string &filename, std::vector<Point<T>> &datas) {
    std::ifstream infile(filename);
    if (!infile.is_open()) {
        std::cerr << "无法打开文件 " << filename << std::endl;
    }

    std::string line;
    while (std::getline(infile, line)) {
        std::istringstream iss(line);
        std::string value;
        Point<T> point;
        std::vector<COEFF_TYPE> coords;

        while (getline(iss, value, ',')) {
            coords.push_back(atof(value.c_str()));
        }

        point.coords = coords;
        datas.emplace_back(point);
    }

    infile.close();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T>
void WritePointsToFileWithNotOid(const std::string &filename, const std::vector<Point<T>> &points) {
    std::ofstream outFile(filename);
    if (outFile.is_open()) {
        for (const auto &point: points) {
            point.Print(outFile);
        }
        outFile.close();
    } else {
        std::cerr << "无法打开文件 " << filename << " 进行写入。" << std::endl;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T>
void WritePointsToFileWithNotOidByNums(const std::string &filename, const std::vector<Point<T>> &points, uint32_t nums) {
    std::ofstream outFile(filename);
    if (outFile.is_open()) {
        for (int i = 0; i < nums; ++i) {
            points[i].Print(outFile);
        }
        outFile.close();
    } else {
        std::cerr << "无法打开文件 " << filename << " 进行写入。" << std::endl;
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////